#include "tcp_receiver.hh"

// Dummy implementation of a TCP receiver

// For Lab 2, please replace with a real implementation that passes the
// automated checks run by `make check_lab2`.

using namespace std;

void TCPReceiver::segment_received(const TCPSegment &seg) {
    const auto &header = seg.header();
    const auto &payload = seg.payload();

    if (header.syn) {
        if (_has_syn)
            return;
        _has_syn = true;
        _isn = header.seqno;
        _abs_seqno = 1;
        if (seg.length_in_sequence_space() == 1)
            return;
    } else if (!_has_syn)
        return;
    else
        _abs_seqno = unwrap(header.seqno, _isn, _abs_seqno);
    if (header.fin) {
        //        if (_has_fin)
        //            return;
        //        _has_fin = true;
    } else if (seg.length_in_sequence_space() == 0)
        return;
    _reassembler.push_substring(payload.copy(), _abs_seqno - 1, header.fin);
}

optional<WrappingInt32> TCPReceiver::ackno() const {
    if (!_has_syn)
        return {};
    return wrap(stream_out().bytes_written() + 1 + stream_out().input_ended(), _isn);
}

size_t TCPReceiver::window_size() const { return _capacity - stream_out().buffer_size(); }
